/////////////////////////////////////////////     File     //////////////////////////////////////////////////
// Author: James Chen
// Filename: Grass.cpp
// Created: Thursday, August 26, 2010 10:22:48 PM
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "./Grass.h"
#include "Vertex.h"

/*---------------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------------------*/

////////////////////// Singleton Implementation Begins //////////////////////
CGrass *CGrass::m_pInstance = 0;

CGrass::CGrass(void): mNumVertices(0), mNumFaces(0), md3dDevice(0), mVB(0), mIB(0)
{
	this->m_vecPosition.x = 0.0f;
	this->m_vecPosition.y = 0.0f;
	this->m_vecPosition.z = 0.0f;

	this->m_fFieldHeight = 0;

	this->m_vecGrassHeight.x = 10.0f;
	this->m_vecGrassHeight.y = 40.0f;

	this->m_fBladeWidth = 3.0f;

	this->m_uiPatches = 1;
	this->m_uiBlades = 1;
}

CGrass::~CGrass(void)
{
	ReleaseCOM(mVB);
	ReleaseCOM(mIB);
}

CGrass *CGrass::GetInstance(void)
{
	if(!m_pInstance)
	{
		m_pInstance = new CGrass;
	}

	return m_pInstance;
}

void CGrass::DeleteInstance(void)
{
	if(m_pInstance)
	{
		delete m_pInstance;
		m_pInstance = 0;
	}
}
/////////////////////// Singleton Implementation Ends ///////////////////////

/*---------------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------------------*/

void CGrass::init(ID3D10Device* device)
{
	ReleaseCOM(mVB);
	ReleaseCOM(mIB);

	md3dDevice = device;
 
	mNumFaces    = this->m_uiBlades;
	mNumVertices = (3 * mNumFaces);

	this->m_vecXBounds.x = -FieldWidth;
	this->m_vecXBounds.y = FieldWidth;

	this->m_vecZBounds.x = -FieldWidth;
	this->m_vecZBounds.y = FieldLength;

	RNGen * RN = RNGen::GetInstance();

	RN->RandF(FASTSEED, this->m_vecXBounds.x, this->m_vecXBounds.y);

	
	// Create vertex buffer
    Vertex vertices[] =
	{
		{D3DXVECTOR3(this->m_vecPosition.x+RN->RandF(FASTSEED, -this->m_fBladeWidth,this->m_fBladeWidth), this->m_vecPosition.y, this->m_vecPosition.z+RN->RandF(FASTSEED, -this->m_fBladeWidth,this->m_fBladeWidth)), BLUE},
		{D3DXVECTOR3(this->m_vecPosition.x+RN->RandF(FASTSEED, -this->m_fBladeWidth,this->m_fBladeWidth), this->m_vecPosition.y, this->m_vecPosition.z+RN->RandF(FASTSEED, -this->m_fBladeWidth,this->m_fBladeWidth)), BLUE},
		{D3DXVECTOR3(this->m_vecPosition.x+RN->RandF(FASTSEED, -this->m_fBladeWidth,this->m_fBladeWidth), this->m_vecPosition.y+RN->RandF(FASTSEED, this->m_vecGrassHeight.x, this->m_vecGrassHeight.y), this->m_vecPosition.z+RN->RandF(FASTSEED, -this->m_fBladeWidth,this->m_fBladeWidth)), BLUE},
    };
	

	/*
	Vertex vertices[mNumVertices];

	for(unsigned int i = 0; i < mNumFaces; i++)
	{
		vertices[(i*3)] = D3DXVECTOR3(this->m_vecPosition.x+RN->RandF(FASTSEED, -this->m_fBladeWidth,this->m_fBladeWidth), this->m_vecPosition.y, this->m_vecPosition.z+RN->RandF(FASTSEED, -this->m_fBladeWidth,this->m_fBladeWidth)), BLUE};
		vertices[(i*3)+1] = D3DXVECTOR3(this->m_vecPosition.x+RN->RandF(FASTSEED, -this->m_fBladeWidth,this->m_fBladeWidth), this->m_vecPosition.y, this->m_vecPosition.z+RN->RandF(FASTSEED, -this->m_fBladeWidth,this->m_fBladeWidth)), BLUE};
		vertices[(i*3)+2] = D3DXVECTOR3(this->m_vecPosition.x+RN->RandF(FASTSEED, -this->m_fBladeWidth,this->m_fBladeWidth), this->m_vecPosition.y+RN->RandF(FASTSEED, this->m_vecGrassHeight.x, this->m_vecGrassHeight.y), this->m_vecPosition.z+RN->RandF(FASTSEED, -this->m_fBladeWidth,this->m_fBladeWidth)), BLUE};
	};
	*/



    D3D10_BUFFER_DESC vbd;
    vbd.Usage = D3D10_USAGE_IMMUTABLE;
    vbd.ByteWidth = sizeof(Vertex) * mNumVertices;
    vbd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    vbd.CPUAccessFlags = 0;
    vbd.MiscFlags = 0;
    D3D10_SUBRESOURCE_DATA vinitData;
    vinitData.pSysMem = vertices;
    HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &mVB));


	// Create the index buffer

	DWORD indices[] = {
		// front face
		0, 1, 2,
	};

	D3D10_BUFFER_DESC ibd;
    ibd.Usage = D3D10_USAGE_IMMUTABLE;
    ibd.ByteWidth = sizeof(DWORD) * mNumFaces*3;
    ibd.BindFlags = D3D10_BIND_INDEX_BUFFER;
    ibd.CPUAccessFlags = 0;
    ibd.MiscFlags = 0;
    D3D10_SUBRESOURCE_DATA iinitData;
    iinitData.pSysMem = indices;
    HR(md3dDevice->CreateBuffer(&ibd, &iinitData, &mIB));
}

void CGrass::draw()
{
	UINT stride = sizeof(Vertex);
    UINT offset = 0;
    md3dDevice->IASetVertexBuffers(0, 1, &mVB, &stride, &offset);
	md3dDevice->IASetIndexBuffer(mIB, DXGI_FORMAT_R32_UINT, 0);
	md3dDevice->DrawIndexed(mNumFaces*3, 0, 0);
}

D3DXVECTOR3 CGrass::GetTargetPosition()
{
	return m_vecPosition;
}

void CGrass::SetPosition(D3DXVECTOR3 &pos)
{
	this->m_vecPosition = pos;
}

void CGrass::SetGrassHeight(float &min, float &max)
{
	this->m_vecGrassHeight.x = min;
	this->m_vecGrassHeight.y = max;
}

void CGrass::SetBladeWidth(float &width)
{
	this->m_fBladeWidth = width;
}